package dwarffortess.web.research;

import org.jdesktop.jdic.desktop.Desktop;
import org.jdesktop.jdic.desktop.DesktopException;
import org.jdesktop.jdic.desktop.Message;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileFilter;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Collections;

import dwarffortress.tools.Logger;

public class MainFrame extends JFrame {
    private JFileChooser dialog;
    private JLabel dfLocationLabel;
    private JLabel dfWorldCountLabel;
    private File dfLocation;
    private JPanel panelTwo;
    private JPanel panelThree;
    private JTextArea logArea;

    private File[] worldDirs = new File[0];
    private JButton researchButton;
    private LogController log;
    private boolean inResearch;

    public MainFrame() {
        setTitle("DwarfFortress Savefile Research Project. Version " + PrefTools.getResearcherVersion());
        setNiceSizeAndLocation();
        handleCorrectWindowClosing();


        dfLocationLabel = new JLabel();
        dfWorldCountLabel = new JLabel();
        logArea = new JTextArea(20, 40);
        logArea.setEditable(false);


        log = new LogController(logArea);
//        log.setLevel(Logger.DEBUG);
        JButton browseButton = new JButton("Browse");
        browseButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JFileChooser fileChooser = createFileChooser();
                if (JFileChooser.APPROVE_OPTION == fileChooser.showOpenDialog(MainFrame.this)) {
                    setCurrentDFDir(fileChooser.getSelectedFile());
                }

            }
        });

        researchButton = new JButton("Research");
        researchButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                startResearch();
            }
        });


        JPanel panelZero = createLinksPanel();

        JPanel panelOne = new JPanel();
        panelOne.setBorder(BorderFactory.createTitledBorder("1. Locate Dwarf Fortress"));
        panelOne.setLayout(new BorderLayout());
        JPanel stub = new JPanel(new BorderLayout());
        stub.add(new JLabel("DF Location : "), BorderLayout.WEST);
        stub.add(dfLocationLabel, BorderLayout.EAST);
        panelOne.add(stub, BorderLayout.WEST);
        panelOne.add(browseButton, BorderLayout.EAST);

        panelTwo = new JPanel(new BorderLayout());
        panelTwo.add(dfWorldCountLabel, BorderLayout.WEST);
        panelTwo.add(researchButton, BorderLayout.EAST);
        panelTwo.setBorder(BorderFactory.createTitledBorder("2. Prepare for Research"));
        panelThree = new JPanel(new BorderLayout());
        panelThree.setBorder(BorderFactory.createTitledBorder("3. Research log"));
        panelThree.add(new JScrollPane(logArea), BorderLayout.CENTER);

        JPanel total = new JPanel();
        total.setLayout(new BoxLayout(total, BoxLayout.Y_AXIS));
        total.add(panelZero);
        total.add(panelOne);
        total.add(panelTwo);

        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(total, BorderLayout.NORTH);
        getContentPane().add(panelThree, BorderLayout.CENTER);
        setCurrentDFDir(PrefTools.getDFPath());

    }

    private JPanel createLinksPanel() {
        JPanel panelZero = new JPanel(new GridLayout(1, 3));
        JLabel label0 = new JLabel("<html><a href=\"http://dwarff.spb.ru/\">Home page</a></html>", JLabel.LEFT);
        label0.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent event) {
                try {
                    Desktop.browse(new URL("http://dwarff.spb.ru/"));
                } catch (DesktopException e) {
                } catch (MalformedURLException e) {
                }
            }
        });
        JLabel label1 = new JLabel("<html><a href=\"http://code.google.com/p/dfresearch/\">Source Code</a></html>", JLabel.CENTER);
        label1.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent event) {
                try {
                    Desktop.browse(new URL("http://code.google.com/p/dfresearch/"));
                } catch (DesktopException e) {
                } catch (MalformedURLException e) {
                }
            }
        });
        JLabel label2 = new JLabel("<html><a href=\"mailto:dfresearchmail@gmail.com?Subject=feedback\">Feedback</a></html>", JLabel.RIGHT);
        label2.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent event) {

                try {
                    Message message = new Message();
                    message.setToAddrs(Collections.singletonList("dfresearchmail@gmail.com"));
                    message.setSubject("[Feedback]");
                    message.setBody("Feedback from DFResearch Tool version " + PrefTools.getResearcherVersion() + "\n\n");

                    Desktop.mail(message);
                } catch (DesktopException e) {
                }

            }
        });
        panelZero.add(label0);
        panelZero.add(label1);
        panelZero.add(label2);
        return panelZero;
    }


    private void setCurrentDFDir(File selectedFile) {
        if (null == selectedFile) {
            dfLocationLabel.setText("Unknown");
            dfLocationLabel.setForeground(Color.RED);
            dfLocation = null;
        } else if (FileLayoutTools.isDFDirectory(selectedFile)) {
            dfLocationLabel.setText(selectedFile.getPath());
            dfLocationLabel.setForeground(Color.GREEN.darker());
            dfLocation = selectedFile;
        } else {
            dfLocationLabel.setForeground(Color.RED);
            dfLocationLabel.setText(selectedFile.getPath());
            dfLocation = null;
        }
        log.clear();
        updatePhaseTwoStatus();
    }


    private void updatePhaseTwoStatus() {
        boolean enabled = (null != dfLocation);

        File saveDir = new File(dfLocation, "data/save");
        FileFilter fileFilter = new FileFilter() {
            public boolean accept(File file) {
                return FileLayoutTools.isDFWorldDirectory(file);
            }
        };
        worldDirs = saveDir.listFiles(fileFilter);
        if (null == worldDirs) {
            worldDirs = new File[0];
        }
        dfWorldCountLabel.setText(String.format("%d world(s) found", worldDirs.length));
        panelTwo.setVisible(enabled);

        updatePhaseThreeStatus();
    }

    private void updatePhaseThreeStatus() {
        researchButton.setEnabled(worldDirs.length > 0 && !inResearch);
        panelThree.setVisible(null != dfLocation);
    }


    private void startResearch() {
        if (inResearch) {
            return;
        }
        inResearch = true;
        log.clear();
        updatePhaseThreeStatus();
        ResearchThread thread = new ResearchThread(this, log, worldDirs);
        thread.start();
    }


    private void handleCorrectWindowClosing() {
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                MainFrame.this.setVisible(false);
                MainFrame.this.dispose();
                if (null != dialog) {
                    PrefTools.setLastFilechooserPathString(dialog.getCurrentDirectory().getAbsolutePath());
                }
                if (null != dfLocation) {
                    PrefTools.setDFPath(dfLocation.getAbsolutePath());
                }
                System.exit(0);
            }
        });
    }

    private void setNiceSizeAndLocation() {
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int height = Math.min(Math.max(400, screenSize.height / 2), screenSize.height);
        int width = Math.min(Math.max(400, screenSize.width / 2), screenSize.width);
        setSize(width, height);
        setLocation((screenSize.width - width) / 2, (screenSize.height - height) / 2);
    }

    private JFileChooser createFileChooser() {
        if (null != dialog) {
            return dialog;
        }
        dialog = new JFileChooser();
        File path = PrefTools.getDFPath();
        if (path != null) {
            dialog.setCurrentDirectory(path);
        } else {
            String lastPath = PrefTools.getLastFilechooserPathString();
            if (null != lastPath) {
                dialog.setCurrentDirectory(new File(lastPath));
            }
        }
        dialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        return dialog;
    }

    public void researchFinished() {
        inResearch = false;
        updatePhaseThreeStatus();
    }
}
